home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / file-tra / wu-ftpd-.000 / wu-ftpd- / wu-ftpd-2.4-fixed / support / authuser.c next >
Encoding:
C/C++ Source or Header  |  1994-04-01  |  3.6 KB  |  160 lines

  1. /*
  2.  * 5/6/91 DJB baseline authuser 3.1. Public domain.
  3.  */
  4.  
  5. #include "../src/config.h"
  6.  
  7. #include <arpa/inet.h>
  8. #include <ctype.h>
  9. #include <errno.h>
  10. #include <fcntl.h>
  11. #include <limits.h>
  12. #include <netdb.h>
  13. #include <netinet/in.h>
  14. #include <stdio.h>
  15. #include <sys/socket.h>
  16. #include <sys/stat.h>
  17. #include <sys/types.h>
  18.  
  19. extern int errno;
  20.  
  21. #include "authuser.h"
  22.  
  23. unsigned short auth_tcpport = 113;
  24.  
  25. #define SIZ 500                    /* various buffers */
  26.  
  27. static int
  28. usercmp(register char *u, register char *v)
  29. {
  30.     /* is it correct to consider Foo and fOo the same user? yes */
  31.     /* but the function of this routine may change later */
  32.     while (*u && *v)
  33.         if (tolower(*u) != tolower(*v))
  34.             return tolower(*u) - tolower(*v);
  35.         else
  36.             ++u, ++v;
  37.     return *u || *v;
  38. }
  39.  
  40. static char authline[SIZ];
  41.  
  42. char *
  43. auth_xline(register char *user, register int fd, register long unsigned int *in)
  44.   /* the supposed name of the user, NULL if unknown */
  45.   /* the file descriptor of the connection */
  46.  
  47. {
  48.     unsigned short local;
  49.     unsigned short remote;
  50.     register char *ruser;
  51.  
  52.     if (auth_fd(fd, in, &local, &remote) == -1)
  53.         return 0;
  54.     ruser = auth_tcpuser(*in, local, remote);
  55.     if (!ruser)
  56.         return 0;
  57.     if (!user)
  58.         user = ruser;            /* forces X-Auth-User */
  59.     (void) sprintf(authline,
  60.             (usercmp(ruser, user) ? "X-Forgery-By: %s" : "X-Auth-User: %s"),
  61.                    ruser);
  62.     return authline;
  63. }
  64.  
  65. int
  66. auth_fd(register int fd, register long unsigned int *in, register short unsigned int *local, register short unsigned int *remote)
  67. {
  68.     struct sockaddr_in sa;
  69.     int dummy;
  70.  
  71.     dummy = sizeof(sa);
  72.     if (getsockname(fd, (struct sockaddr *)&sa, &dummy) == -1)
  73.         return -1;
  74.     if (sa.sin_family != AF_INET) {
  75.         errno = EAFNOSUPPORT;
  76.         return -1;
  77.     }
  78.     *local = ntohs(sa.sin_port);
  79.     dummy = sizeof(sa);
  80.     if (getpeername(fd, (struct sockaddr *)&sa, &dummy) == -1)
  81.         return -1;
  82.     *remote = ntohs(sa.sin_port);
  83.     *in = sa.sin_addr.s_addr;
  84.     return 0;
  85. }
  86.  
  87. static char ruser[SIZ];
  88. static char realbuf[SIZ];
  89. static char *buf;
  90.  
  91. char *
  92. auth_tcpuser(register long unsigned int in, register short unsigned int local, register short unsigned int remote)
  93. {
  94.     struct sockaddr_in sa;
  95.     register int s;
  96.     register int buflen;
  97.     register int w;
  98.     register int saveerrno;
  99.     char ch;
  100.     unsigned short rlocal;
  101.     unsigned short rremote;
  102.  
  103.     if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  104.         return 0;
  105.     sa.sin_family = AF_INET;
  106.     sa.sin_port = htons(auth_tcpport);
  107.     sa.sin_addr.s_addr = in;
  108.     if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
  109.         saveerrno = errno;
  110.         (void) close(s);
  111.         errno = saveerrno;
  112.         return 0;
  113.     }
  114.     buf = realbuf;
  115.     (void) sprintf(buf, "%u , %u\r\n", (unsigned int) remote, (unsigned int) local);
  116.     /* note the reversed order---the example in the RFC is misleading */
  117.     buflen = strlen(buf);
  118.     while ((w = write(s, buf, buflen)) < buflen)
  119.         if (w == -1) {            /* should we worry about 0 as well? */
  120.             saveerrno = errno;
  121.             (void) close(s);
  122.             errno = saveerrno;
  123.             return 0;
  124.         } else {
  125.             buf += w;
  126.             buflen -= w;
  127.         }
  128.     buf = realbuf;
  129.     while ((w = read(s, &ch, 1)) == 1) {
  130.         *buf = ch;
  131.         if ((ch != ' ') && (ch != '\t') && (ch != '\r'))
  132.             ++buf;
  133.         if ((buf - realbuf == sizeof(realbuf) - 1) || (ch == '\n'))
  134.             break;
  135.     }
  136.     if (w == -1) {
  137.         saveerrno = errno;
  138.         (void) close(s);
  139.         errno = saveerrno;
  140.         return 0;
  141.     }
  142.     *buf = '\0';
  143.  
  144.     if (sscanf(realbuf, "%hd,%hd: USERID :%*[^:]:%s", &rremote, &rlocal, ruser) < 3) {
  145.         (void) close(s);
  146.         errno = EIO;
  147.         /* makes sense, right? well, not when USERID failed to match ERROR */
  148.         /* but there's no good error to return in that case */
  149.         return 0;
  150.     }
  151.     if ((remote != rremote) || (local != rlocal)) {
  152.         (void) close(s);
  153.         errno = EIO;
  154.         return 0;
  155.     }
  156.     /* XXX: we're not going to do any backslash processing */
  157.     (void) close(s);
  158.     return ruser;
  159. }
  160.